//
//  YFNetWorkManager.swift
//  仿新浪微博
//
//  Created by 杨帆 on 16/7/2.
//  Copyright © 2016年 杨帆. All rights reserved.


import UIKit
import AFNetworking
// Switf 的枚举支持任意数据类型 Switf / enum 在OC中只支持整数
enum YFHTTPMethod {
    
    case GET
    case POST
}
// 网络管理工具
class YFNetWorkManager: AFHTTPSessionManager {
    
    // 保存在静态区(常量)/闭包
    // 在第一次访问时 执行闭包 将结果保存在shard 常量中
    static let shared: YFNetWorkManager = {
        // 实例化对象
        let instance = YFNetWorkManager()
        
        //设置响应反序列化支持的数据类型
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        //返回对象
        return instance
    }()

    // 用户账户的懒加载属性
    lazy var userAccount = YFUserAccount()
    //用户登录标记(计算型属性)
    var userLogon: Bool {
        
        return userAccount.access_token != nil
    }
    
    // 专门负责拼接 token的网络请求方法
    func tokenRequest(method: YFHTTPMethod = .GET, URLString: String, parameters: [String: AnyObject]?, completion: (json :AnyObject?, isSuccess: Bool)->()) {
    
        // 处理token字典
        // 0> 判断 token是否为nil 为nil直接返回
        guard let token = userAccount.access_token else {
            
            // 发送通知 提示用户登录
            print("没有 token! 需要登录")
 
            NotificationCenter.default.post(
            
                name: NSNotification.Name(rawValue: YFUserShouldLoginNotification),
                object: nil)
            
            completion(json: nil, isSuccess: false)
            
            return
        }
        
        // 1> 判断 参数字典是否存在如果为nil 应该新建一个字典
        var parameters = parameters
        if parameters == nil {
            
            //实例化字典
            parameters = [String: AnyObject]()
        }
        
        // 2> 设置参数字典 代码在此处字典一定有值
        parameters!["access_token"] = token
        
        // 调用request 发起真正的网络请求方法
        request(method: method, URLString: URLString, parameters: parameters, completion: completion)
        
    }
    
    // 封装AFN的GET / POST请求
    /// - parameter method:     GET / POST
    /// - parameter URLString:  URLString
    /// - parameter parameters: 参数字典
    /// - parameter completion: 完成回调[json(字典／数组), 是否成功]
        func request(method: YFHTTPMethod = .GET, URLString: String, parameters: [String: AnyObject]?, completion: (json: AnyObject?, isSuccess: Bool)->()) {

        
        // 成功回调
        let success = { (task: URLSessionDataTask, json: AnyObject?)->() in
            
            completion(json: json, isSuccess: true)
            
            
        }
        
        // 失败对调
        let failure = { (task: URLSessionDataTask?, error: NSError)->() in
            
            // 针对 403错误处理用户 token 过期
            //解决办法 新建一个应用程序
            if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                
                print("token 过期了")
                
                // 发送通知 提示用户再次登录 不知道被谁调用 谁接收到通知谁处理
                NotificationCenter.default.post(
                    name: NSNotification.Name(rawValue: YFUserShouldLoginNotification),
                    object: "bad token")

            }
            
            print("网络请求错误 \(error)")
            
            completion(json: nil, isSuccess: false)
        }
        
        if method == .GET {
            
            get(URLString, parameters:  parameters, progress: nil, success: success, failure: failure)
        } else {

            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
    }
}

/*
 Objective-c(OC)单例代码
 +(instancetype) shareInstance ;
 
 +(instancetype) shareInstance
 {
 static dispatch_once_t onceToken ;
 dispatch_once(&onceToken, ^{
 _instance = [[self alloc] init] ;
 }) ;
 
 return _instance ;
 }
 
 具体使用方法
 Singleton* obj1 = [Singleton shareInstance] ;
 NSLog(@"obj1 = %@.", obj1) ;
 
 Singleton* obj2 = [Singleton shareInstance] ;
 NSLog(@"obj2 = %@.", obj2) ;
 
 Singleton* obj3 = [[Singleton alloc] init] ;
 NSLog(@"obj3 = %@.", obj3) ;
 }
 return 0;
 
 输出结果为
 ObjcSingleton[8847:303] obj1 = <singleton: 0x1001086e0="">.
 ObjcSingleton[8847:303] obj2 = <singleton: 0x1001086e0="">.
 ObjcSingleton[8847:303] obj3 = <singleton: 0x100103940="">.
 </singleton:></singleton:></singleton:>
 */

